package com.agentlab.imitation.util;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;

public class RandomNumUtil {

    private ByteArrayInputStream image;//图像  
    private String str;//验证码  
    private int charNum = 4; //字符个数
    private boolean isDigitOnly = false; //是否全为数字
      
    private RandomNumUtil(){  
        init();//初始化属性  
    } 
    private RandomNumUtil(int charnum,boolean isDigit){  
    	this.charNum = charnum;
    	this.isDigitOnly = isDigit;
        init();//初始化属性  
    } 
    /* 
     * 取得RandomNumUtil实例 
     */  
    public static RandomNumUtil Instance(){  
        return new RandomNumUtil();  
    }  
    /* 
     * 取得RandomNumUtil实例 
     */  
    public static RandomNumUtil Instance(int charnum,boolean isDigit){  
        return new RandomNumUtil(charnum,isDigit);  
    }  
    /* 
     * 取得验证码图片 
     */  
    public ByteArrayInputStream getImage(){  
        return this.image;  
    }  
    /* 
     * 取得图片的验证码 
     */  
    public String getString(){  
        return this.str;  
    }  
      
    private void init() {  
        //       在内存中创建图象  
        int width=90, height=20;  
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
        //       获取图形上下文  
        Graphics g = image.getGraphics();  
        Graphics2D g2d=(Graphics2D)g;
        //      生成随机类  
        Random random = new Random();  
        //       设定背景色  
        g.setColor(getRandColor(200,250));  
        g.fillRect(0, 0, width, height);  
        //      设定字体  
        g.setFont(new Font("Times New Roman",Font.PLAIN,18));  
        //		随机产生155条干扰线，使图象中的认证码不易被其它程序探测到  
        g.setColor(getRandColor(180,200)); 
        
      //画随机的线条
		for (int i = 0; i < 130; i++) {
			int x = random.nextInt(width - 1);
			int y = random.nextInt(height - 1);
			int x1 = random.nextInt(6) + 1;
			int y1 = random.nextInt(12) + 1;
			BasicStroke bs=new BasicStroke(2f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);
			Line2D line=new Line2D.Double(x,y,x+x1,y+y1);
			g2d.setStroke(bs);
			g2d.draw(line);
		}
		
        for (int i=0;i<155;i++)  
        {  
         int x = random.nextInt(width);  
         int y = random.nextInt(height);  
                int xl = random.nextInt(12);  
                int yl = random.nextInt(12);  
         g.drawLine(x,y,x+xl,y+yl);  
        }  
        //       取随机产生的认证码(6位数字)  
        /*String sRand="";  
        for (int i=0;i<6;i++){ 
            String rand=String.valueOf(random.nextInt(10));  
            sRand+=rand;  
            // 将认证码显示到图象中  
            g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));  
            //      调用函数出来的颜色相同，可能是因为种子太接近，所以只能直接生成  
            g.drawString(rand,13*i+6,16);  
            this.str=rand;   赋值验证码     
        }*/
        
        String sRand="";
		//输出随机的验证文字(charNum位字符)  
		int itmp=0;
		for(int i=0;i<charNum;i++){
			if(random.nextInt(2)==1 && isDigitOnly==false){
				itmp=random.nextInt(26)+65;	//生成A~Z的字母
			}else{
				itmp=random.nextInt(10)+48;	//生成0~9的数字
			}
			char ctmp=(char)itmp;
			sRand+=String.valueOf(ctmp);
			Color color=new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110));
			g.setColor(color);
			/****随机缩放文字并将文字旋转指定角度**/
			//将文字旋转指定角度
			Graphics2D g2d_word=(Graphics2D)g;
			AffineTransform trans=new AffineTransform();
			trans.rotate(random.nextInt(45)*3.14/180,15*i+10,6);
			//缩放文字
			float scaleSize=random.nextFloat()+0.5f;
			if(scaleSize<0.8 || scaleSize>1.1f) scaleSize=1f;
			trans.scale(scaleSize, scaleSize);
			g2d_word.setTransform(trans);
			/************************/
			g.drawString(String.valueOf(ctmp),15*i+10,14);

		}
		this.str =sRand;
        //       图象生效  
        g.dispose();  
        ByteArrayInputStream input=null;  
        ByteArrayOutputStream output = new ByteArrayOutputStream();  
        try{  
            ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);  
            ImageIO.write(image, "JPEG", imageOut);  
            imageOut.close();  
            input = new ByteArrayInputStream(output.toByteArray());  
        }catch(Exception e){  
            System.out.println("验证码图片产生出现错误："+e.toString());  
        }  
          
        this.image=input;/*  赋值图像  */  
    }  
    /* 
     * 给定范围获得随机颜色 
     */  
    private Color getRandColor(int fc,int bc){  
        Random random = new Random();  
        if(fc>255) fc=255;  
        if(bc>255) bc=255;  
        int r=fc+random.nextInt(bc-fc);  
        int g=fc+random.nextInt(bc-fc);  
        int b=fc+random.nextInt(bc-fc);  
        return new Color(r,g,b);  
   }  
}
